#include "Panels.h"

#include "data\slide_show.hpp"
#include "Communicate.h"
#include <resource_cache\resource_cache.hpp>
#include "string_conv.h"
#include "UI\interface_ids.hpp"
#include "shortcuts.hpp"

#define BODIES g_slides.slides[g_slides.current_slide].bodys
#define CSLIDE g_slides.slides[g_slides.current_slide]
#define CBODY CSLIDE.bodys[g_slides.slides[g_slides.current_slide].current_body]
#define BODYUI m_slide_data.m_body_ui
#define SHAPEUI m_slide_data.m_shape_ui
#define CSHAPE CBODY.shapes[CBODY.current_shape]

void LeftPanel::clear_body_ui()
{
	BODYUI.m_angle.set_text( "" );
	BODYUI.m_name.set_text( "" );
	BODYUI.m_animation.set_text( "" );
	BODYUI.m_positionX.set_text( "" );
	BODYUI.m_positionY.set_text( "" );
	BODYUI.m_dampening.set_text( "" );
	BODYUI.m_angular_dampening.set_text( "" );
	BODYUI.m_fixed_rotation->SetValue( false );
	BODYUI.m_kinematics->Clear();
	BODYUI.m_bodys->Clear();
	SHAPEUI.m_shapes->Clear();
	SHAPEUI.m_vertices->Clear();
}

void LeftPanel::set_to_current_body_ui()
{
	if( !active_body())
		return;

	BODYUI.m_angle.set_text( stringify( CBODY.angle) );
	BODYUI.m_name.set_text( CBODY.name );
	BODYUI.m_animation.set_text( CBODY.animation_file );
	BODYUI.m_positionX.set_text( stringify( CBODY.position.x) );
	BODYUI.m_positionY.set_text( stringify( CBODY.position.y) );
	BODYUI.m_dampening.set_text( stringify( CBODY.dampening ) );
	BODYUI.m_angular_dampening.set_text( stringify( CBODY.angular_dampening ) );
	BODYUI.m_fixed_rotation->SetValue( CBODY.fixed_angle );
	BODYUI.m_kinematics->Clear();
	for( unsigned int kineP = 0; kineP < CBODY.kinematic_points.size(); ++ kineP )
	{
		std::string kp_name;
		kp_name.append( "x:" );
		kp_name.append( stringify(CBODY.kinematic_points[kineP].point.x) );
		kp_name.append( " y:" );
		kp_name.append( stringify(CBODY.kinematic_points[kineP].point.y) );
		BODYUI.m_kinematics->Append(kp_name.c_str());
	}
	set_to_current_shape_ui();
	SHAPEUI.m_shapes->Clear();
	SHAPEUI.m_vertices->Clear();
	for( unsigned int i = 0; i < CBODY.shapes.size(); ++i )
	{
		std::string s_name;
		if( CBODY.shapes[i].shape_type == shape_circle )
			s_name.append( "Circle Shape" );
		else
			s_name.append( "Polygon Shape" );

		SHAPEUI.m_shapes->Append(s_name.c_str());
	}
	adjust_body_ui_to_type(CBODY.body_type);
}

void LeftPanel::on_new_body(wxCommandEvent & WXUNUSED(e))
{
	if( !active_slide())
		return;

	body new_body;
	CSLIDE.bodys.push_back( new_body );
	m_slide_data.m_body_ui.m_bodys->Append( wxT("New Body" ) );
}
void LeftPanel::on_delete_body(wxCommandEvent & WXUNUSED(e))
{
	if( !active_body())
		return;

	m_slide_data.m_body_ui.m_bodys->Delete( CSLIDE.current_body );
	BODIES.erase(BODIES.begin() + CSLIDE.current_body );
}
void LeftPanel::on_switch_static(wxCommandEvent & WXUNUSED(e))
{
	if( !active_body())
		return;

	BODYUI.m_dynamic->Enable(true);
	BODYUI.m_kinematic->Enable(true);
	BODYUI.m_static->Enable(false);
	CBODY.body_type = body_static;
	adjust_body_ui_to_type(body_static);
}
void LeftPanel::on_switch_kinematic(wxCommandEvent & WXUNUSED(e))
{
	if( !active_body())
		return;

	BODYUI.m_dynamic->Enable(true);
	BODYUI.m_kinematic->Enable(false);
	BODYUI.m_static->Enable(true);
	CBODY.body_type = body_kinematic;
	adjust_body_ui_to_type(body_kinematic);
}
void LeftPanel::on_switch_dynamic(wxCommandEvent & WXUNUSED(e))
{
	if( !active_body())
		return;

	BODYUI.m_dynamic->Enable(false);
	BODYUI.m_kinematic->Enable(true);
	BODYUI.m_static->Enable(true);
	CBODY.body_type = body_dynamic;
	adjust_body_ui_to_type(body_dynamic);
}

void LeftPanel::adjust_body_ui_to_type( int type )
{
	if( !active_body())
		return;

	if( type == body_kinematic )
	{
		BODYUI.m_active_kinematic->Show(true);
		BODYUI.m_append_kinematic->Show(true);
		BODYUI.m_delete_kinematic->Show(true);
		BODYUI.m_kinematics->Show(true);
		BODYUI.m_kineX.Show(true);
		BODYUI.m_kineY.Show(true);
		BODYUI.m_kine_angle.Show(true);
		BODYUI.m_kine_time.Show(true);

		BODYUI.m_active_position->Show(false);
		BODYUI.m_positionX.Show(false);
		BODYUI.m_positionY.Show(false);

		BODYUI.m_dynamic->Enable(true);
		BODYUI.m_kinematic->Enable(false);
		BODYUI.m_static->Enable(true);
	}
	else
	{
		BODYUI.m_active_kinematic->Show(false);
		BODYUI.m_append_kinematic->Show(false);
		BODYUI.m_delete_kinematic->Show(false);
		BODYUI.m_kinematics->Show(false);
		BODYUI.m_kineX.Show(false);
		BODYUI.m_kineY.Show(false);
		BODYUI.m_kine_angle.Show(false);
		BODYUI.m_kine_time.Show(false);

		BODYUI.m_active_position->Show(true);
		BODYUI.m_positionX.Show(true);
		BODYUI.m_positionY.Show(true);
	}

	if( type == body_dynamic )
	{
		BODYUI.m_dampening.Show(true);
		BODYUI.m_angular_dampening.Show(true);
		BODYUI.m_fixed_rotation->Show(true);

		BODYUI.m_dynamic->Enable(false);
		BODYUI.m_kinematic->Enable(true);
		BODYUI.m_static->Enable(true);
	}
	else if( type == body_static )
	{
		BODYUI.m_dynamic->Enable(true);
		BODYUI.m_kinematic->Enable(true);
		BODYUI.m_static->Enable(false);
		BODYUI.m_dampening.Show(false);
		BODYUI.m_angular_dampening.Show(false);
		BODYUI.m_fixed_rotation->Show(false);
	}
	else
	{
		
	}
}

void LeftPanel::on_browse_animation(wxCommandEvent & WXUNUSED(e))
{
	if( !active_body())
		return;

	wxFileDialog * openFileDialog = new wxFileDialog(this);

	wxString file_name;
	if (openFileDialog->ShowModal() == wxID_OK)
	{
		file_name = openFileDialog->GetPath();  
	}

	std::string f = file_name;
	// TODO check to make sure .xml
	CBODY.set_animation( f );
	BODYUI.m_animation.set_text( file_name );
	delete openFileDialog;
}
void LeftPanel::on_active_position(wxCommandEvent & WXUNUSED(e))
{
	if( !active_body())
		return;

	g_slides.active_body_pos = !g_slides.active_body_pos;
	if( g_slides.active_body_pos )
	{
		BODYUI.m_active_position->SetLabel( "ACTIVE" );
		BODYUI.m_active_position->SetBackgroundColour( wxColour( "blue" ) );
	}
	else
	{
		BODYUI.m_active_position->SetLabel( "inactive" );
		BODYUI.m_active_position->SetBackgroundColour( wxColour( "none" ) );
	}
}
void LeftPanel::on_active_kinematic(wxCommandEvent & WXUNUSED(e))
{
	if( !active_body())
		return;
	int ckine  = CBODY.current_kinematic;
	if( ckine < 0 || ckine >= (int)CBODY.kinematic_points.size())
		return;

	g_slides.active_kine_pos = !g_slides.active_kine_pos;
	if( g_slides.active_kine_pos )
	{
		BODYUI.m_active_kinematic->SetLabel( "ACTIVE" );
		BODYUI.m_active_kinematic->SetBackgroundColour( wxColour( "blue" ) );
	}
	else
	{
		BODYUI.m_active_kinematic->SetLabel( "inactive" );
		BODYUI.m_active_kinematic->SetBackgroundColour( wxColour( "none" ) );
	}
}
void LeftPanel::on_append_kinematic(wxCommandEvent & WXUNUSED(e))
{
	if( !active_body())
		return;

	kine_point kp;
	CBODY.kinematic_points.push_back(kp);
	std::string kp_name;
	kp_name.append( "x:" );
	kp_name.append( stringify(kp.point.x) );
	kp_name.append( " y:" );
	kp_name.append( stringify(kp.point.y) );
	BODYUI.m_kinematics->Append(kp_name.c_str());
}
void LeftPanel::on_delete_kinematic(wxCommandEvent & WXUNUSED(e))
{
	if( !active_body())
		return;
	int ckine  = CBODY.current_kinematic;
	if( ckine < 0 || ckine >= (int)CBODY.kinematic_points.size())
		return;

	BODYUI.m_kinematics->Delete( ckine );
	CBODY.kinematic_points.erase( CBODY.kinematic_points.begin() + ckine );
}
void LeftPanel::on_select_body(wxCommandEvent & WXUNUSED(e))
{
	if( !active_slide())
		return;
	int selection = BODYUI.m_bodys->GetSelection();

	if( selection < 0 || selection >= (int)g_slides.slides[g_slides.current_slide].bodys.size() )
		return;

	CSLIDE.current_body = selection;
	set_to_current_body_ui();
}
void LeftPanel::on_select_kinematic(wxCommandEvent & WXUNUSED(e) )
{
	if( !active_body())
		return;
	int selection = BODYUI.m_kinematics->GetSelection();

	if( selection < 0 || selection >= (int)CBODY.kinematic_points.size() )
		return;

	CBODY.current_kinematic = selection;
	kine_point const& ckinep = CBODY.kinematic_points[CBODY.current_kinematic];
	BODYUI.m_kineX.set_text( stringify(ckinep.point.x) );
	BODYUI.m_kineY.set_text( stringify(ckinep.point.y) );
	BODYUI.m_kine_time.set_text( stringify(ckinep.time) );
	BODYUI.m_kine_angle.set_text( stringify(ckinep.angle) );
}
void LeftPanel::on_change_body_name(wxCommandEvent & e)
{
	if( !active_body())
		return;
	CBODY.name = e.GetString();
	BODYUI.m_bodys->SetString( CSLIDE.current_body, e.GetString() );
}
void LeftPanel::on_change_anim_file(wxCommandEvent & e)
{
	if( !active_body())
		return;
	CBODY.animation_file = e.GetString();
}
void LeftPanel::on_change_angle(wxCommandEvent & e)
{
	if( !active_body())
		return;
	CBODY.angle = ::atof(e.GetString().char_str());
}
void LeftPanel::on_change_pos_x(wxCommandEvent & e)
{
	if( !active_body())
		return;
	CBODY.position.x = ::atof(e.GetString().char_str());
}
void LeftPanel::on_change_pos_y(wxCommandEvent & e)
{
	if( !active_body())
		return;
	CBODY.position.y = ::atof(e.GetString().char_str());
}
void LeftPanel::on_change_dampening(wxCommandEvent & e)
{
	if( !active_body())
		return;
	CBODY.dampening = ::atof(e.GetString().char_str());
}
void LeftPanel::on_change_angular_dampening(wxCommandEvent & e)
{
	if( !active_body())
		return;
	CBODY.angular_dampening = ::atof(e.GetString().char_str());
}
void LeftPanel::on_change_kine_x(wxCommandEvent & e)
{
	if( !active_body())
		return;
	int ckine  = CBODY.current_kinematic;
	if( ckine < 0 || ckine >= (int)CBODY.kinematic_points.size())
		return;
	CBODY.kinematic_points[ckine].point.x = ::atof(e.GetString().char_str());
}
void LeftPanel::on_change_kine_y(wxCommandEvent & e)
{
	if( !active_body())
		return;
	int ckine  = CBODY.current_kinematic;
	if( ckine < 0 || ckine >= (int)CBODY.kinematic_points.size())
		return;
	CBODY.kinematic_points[ckine].point.y = ::atof(e.GetString().char_str());
}
void LeftPanel::on_change_kine_time(wxCommandEvent & e)
{
	if( !active_body())
		return;
	int ckine  = CBODY.current_kinematic;
	if( ckine < 0 || ckine >= (int)CBODY.kinematic_points.size())
		return;
	CBODY.kinematic_points[ckine].time = ::atof(e.GetString().char_str());
}
void LeftPanel::on_change_kine_angle(wxCommandEvent & e)
{
	if( !active_body())
		return;
	int ckine  = CBODY.current_kinematic;
	if( ckine < 0 || ckine >= (int)CBODY.kinematic_points.size())
		return;
	CBODY.kinematic_points[ckine].angle = ::atof(e.GetString().char_str());
}
void LeftPanel::on_check_fixed_rot(wxCommandEvent & WXUNUSED(e))
{
	if( !active_body())
		return;
	CBODY.fixed_angle = BODYUI.m_fixed_rotation->GetValue();
}